package com.cictec.middleware.gps.engine.position.handler.shiftAndTrip;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cictec.middleware.commons.utils.NumberUtil;
import com.cictec.middleware.commons.utils.PropertiesUtils;
import com.cictec.middleware.commons.utils.ThreadUtils;
import com.cictec.middleware.feign.gps.caculate.MiddlewareGpsCaculateService;
import com.cictec.middleware.gps.engine.BusInstance;
import com.cictec.middleware.gps.engine.TimingPoint;
import com.cictec.middleware.gps.engine.caculate.entity.BusMileage;
import com.cictec.middleware.gps.engine.caculate.entity.BusTrip;
import com.cictec.middleware.gps.engine.service.DataStorageToRedisService;
import com.cictec.middleware.gps.service.DailyOperaTripService;

/**
 * 实时趟次计算
 * @author ql
 */
@Service
public class RealTripCaculateHandler {

	@Autowired
	private MiddlewareGpsCaculateService middlewareGpsCaculateService;
	@Autowired
	private DataStorageToRedisService dataStorageToRedisService;
	@Autowired
	private DailyOperaTripService dailyOperaTripService;
	
	// 以下是新的实时趟次计算
	private static ThreadPoolExecutor pool = ThreadUtils.getFixedThreadPool("point-execute-thread-", 4);
	
	
	
	/**
	 * 实时趟次计算
	 * @param busInstance
	 * @param preBusTrip
	 */
	public void realTripCaculate(BusInstance busInstance, BusTrip preBusTrip){
		
		caculateMileage(busInstance, preBusTrip);			// 同步方式计算
//		pool.submit(new RealTripCaculateRunable(busInstance, preBusTrip));// 异步方式计算
		
	}
	
	/**
	 * 同步执行
	 * @param busInstance
	 * @param busTrip
	 */
	private void caculateMileage(BusInstance busInstance, BusTrip busTrip){
		// 【计算趟次里程信息】
		List<TimingPoint> points = dataStorageToRedisService.getPositionFromRedis(busTrip.getPlate(), busTrip.getStartTime(), busTrip.getEndTime());
		List<BusMileage> busMileages = middlewareGpsCaculateService.caculateMileage(points);
		double mileage = 0;
		for (BusMileage busMileage : busMileages) {
			mileage += busMileage.getMileage();
		}
		mileage = NumberUtil.round(mileage, 2);
		busTrip.setMileage(mileage);
		
		
		// 保存车辆【实时】趟次数据
		dataStorageToRedisService.saveBusTripToRedis(busTrip.getPlate(), busTrip);
		
		// 是否实时计算日运营信息
		boolean realTripCaculate = PropertiesUtils.getBoolean("system.parameter.trip.realcaculate", false);
		if(realTripCaculate){
			dailyOperaTripService.saveTrip(busInstance.getBusUuid(), busTrip, busMileages);
		}
	}
	
	/**
	 * 异步趟次里程信息统计计算
	 * @author ql
	 */
	class RealTripCaculateRunable implements Callable<String> {
		
		private BusTrip busTrip;
		private BusInstance busInstance;

		public RealTripCaculateRunable(BusInstance busInstance, BusTrip busTrip) {
			this.busTrip = busTrip;
			this.busInstance = busInstance;
		}

		@Override
		public String call() throws Exception {
			
			try {
				caculateMileage(busInstance, busTrip);
			} catch (Exception e) {
				e.printStackTrace();
				return "";
			}
			return "";
		}
	}
}


